/*
 * <one line to give the program's name and a brief idea of what it does.>
 * Copyright (C) 14-ago-2011 lichfolky
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see http://www.gnu.org/licenses/.
 * 
 * Copyright (C) 14-ago-2011 lichfolky
 * This program comes with ABSOLUTELY NO WARRANTY; This is free software, and you
 * are welcome to redistribute it under certain conditions;
 */

package ailabproject2011;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

/**
 * GridImagePanel - a rectangular grid of images
 */
public class GridImagePanel extends JPanel {
   /** The LayoutManager. We provide it, not the user */
   protected LayoutManager lm = null;
   /** The list of Images */
   protected Vector vi = new Vector();
   /** The name of each Image */
   protected Vector vs = new Vector();
   /** The Panel, to manage the grid */
   Panel grid;
   /** The label, for showStatus */
   Label status;

   /** Construct a GridImagePanel */
   GridImagePanel() {
      setBackground(Color.red);
      grid = new Panel();
      status = new Label("Status here");
      setLayout(new BorderLayout());
      add(BorderLayout.CENTER, grid);
      add(BorderLayout.SOUTH, status);
   }

   /** Main program to allow interactive use */
   public static void main(String[] argv) {
      System.out.println("GridImagePanel demo starting...");
      if (argv.length == 0)
         throw new IllegalArgumentException("Usage: GridImagePanel image...");
      final Frame f = new Frame("GridImagePanel");
      f.setLayout(new FlowLayout());
        f.addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            f.setVisible(false);
            f.dispose();
            System.exit(0);
         }
      });
      GridImagePanel gic;
      f.add(gic = new GridImagePanel());
      for (int i=0; i<argv.length; i++) {
         Image im = Toolkit.getDefaultToolkit().getImage(argv[i]);
         gic.addImage(im, argv[i]);
      }
      gic.doLayout();
      f.pack();
      f.show();
   }
   public void addImage(Image i, String s) {
      vi.addElement(i);
      vs.addElement(s);
   }
   /** We do all the Layout setup here, then call Panel.doLayout() */
   public void doLayout() {
      // doLayout called more than once?
      if (lm != null) {
         super.doLayout();
         return;
      }
      int l = vi.size();
      if (l == 0) {
         throw new IllegalArgumentException("doLayout before addImage");
      }
      if (l < 4) {
         throw new IllegalArgumentException("doLayout with <4 images");
      }
      double d = Math.sqrt((double)l);
      int w;
      if (d%1 != 0.0){
         w = ((int)d)+1;
      } else
         w = (int)d;
System.out.println("N="+l+";sqrt="+d+";gridLayout("+w+","+w+");");
      grid.setLayout(lm = new GridLayout(w, w));
      for (int i=0; i<l; i++) {
         ImageElement ic = new ImageElement((Image)vi.elementAt(i),
               (String)vs.elementAt(i));
         grid.add(ic);
      }
      super.doLayout();
   }

   /** dummy add(), to ensure add is NOT called directly.
    @exception   java.lang.IllegalArgumentException   This class does its own adding; use addImage() instead.
    */
   public Component add(Component c) {
         throw new IllegalArgumentException("add not allowed here");
   }

   public void showStatus(String s) {
      status.setText(s);
   }

   /** Inner class ImageElement - helper class,
    * used only by ImageElement, to store
    * an image and a String, paint the Image
    * When the mouse is in our window, we showStatus() the String.
    */
   class ImageElement extends JComponent {
      final int PAD = 3;
      String name;
      Image im = null;
      int w, h;
      ImageElement(Image i, String s) {
         name = s;
         im = i;
         MediaTracker mt = new MediaTracker(this);
         mt.addImage(im, 0);
         try {
            mt.waitForID(0);
         } catch(InterruptedException e) {
            throw new IllegalArgumentException(
               "Unexpected InterruptedException");
         }
         if (mt.isErrorID(0)) {
            throw new IllegalArgumentException(
               "Couldn't load image " + s);
         }
         addMouseListener(new MouseAdapter() {
            public void mouseEntered(MouseEvent e) {
               showStatus(name);
            }
            public void mouseExited(MouseEvent e) {
               showStatus("");
            }
         });
         setSize(w = im.getWidth(this), h = im.getHeight(this));
         repaint();
      }

      public Dimension getMinimumSize() {
         // System.out.println("getMinimumSize() returns ("+w+","+h+");");
         return new Dimension(w, h);
      }
      public Dimension getPreferredSize() {
         // System.out.println("getPreferredSize() returns ("+w+","+h+");");
         return new Dimension(w+PAD, h+PAD);
      }
      public Dimension getMaximumSize() {
         // System.out.println("getMaximumSize() returns ("+w+","+h+");");
         return new Dimension(w, h);
      }
      public void paint(Graphics g) {
         if (im == null) {
            g.setColor(Color.red);
            g.fillRect(0, 0, w, h);
         } else
            g.drawImage(im, 0, 0, this);
      }
   }
}


